package com.lizard.schedule.ui.fragment;

import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;

import com.handmark.pulltorefresh.library.PullToRefreshBase;
import com.handmark.pulltorefresh.library.PullToRefreshWebView;
import com.lizard.schedule.R;
import com.lizard.schedule.log.ScheduleLog;
import com.lizard.schedule.manager.AccountManager;
import com.lizard.schedule.manager.ScheduleSyncManager;
import com.lizard.schedule.manager.observer.ObserverIfaces;
import com.lizard.schedule.manager.observer.ObserverManager;
import com.lizard.schedule.persistence.db.bean.Schedule;
import com.lizard.schedule.persistence.db.table.ScheduleTbl;
import com.lizard.schedule.persistence.sharedpreferences.SyncTimePref;
import com.lizard.schedule.ui.activity.EditScheduleActivity;
import com.lizard.schedule.ui.adapter.schedule.ScheduleListAdapter;
import com.lizard.schedule.ui.fragment.base.BaseFragment;
import com.lizard.schedule.ui.view.schedulelist.ScheduleListView;
import com.lizard.schedule.utils.RepeatScheduleUtil;
import com.lizard.schedule.utils.TimeUtil;
import com.lizard.schedule.wear.Sender;
import com.lizard.schedule.widget.ScheduleToast;

import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;

/**
 * 我的计划
 */
public class MyScheduleFragment extends BaseFragment implements
        View.OnClickListener,
        PullToRefreshBase.OnRefreshListener, AbsListView.OnScrollListener ,
        ObserverIfaces.UpdateScheduleToUi,
        ObserverIfaces.SyncListener {

    public static final String TAG = MyScheduleFragment.class.getSimpleName();;

    public static final int PAGE_SIZE = 20;

    /**
     * 下拉刷新延迟结束时间
     */
    public static final long REFRESH_COMPLETE_DELAY = 500l;

    private ScheduleListView mScheduleList;

    private PullToRefreshWebView mNonPullToRefresh;

    /**
     * 无任何计划时的提示添加view
     */
    private View mScheduleNone;

    private ScheduleListAdapter mScheduleListAdapter;

    private View mContentView;

    private Handler mHandler;

    /**
     * 下拉刷新的最近一次更新时间刷新定时器
     */
    private Timer mLastSyncTimeTimer;

    /**
     * 正在加载更多
     */
    private boolean mLoadingMore = false;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mHandler = new Handler();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        mContentView = inflater.inflate(R.layout.my_schedule, container, false);
        initView();
        setViewClick();
        return mContentView;
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        registObservers();

        loadMore();

        // wear同步
        Sender.sendSchedules();

        ScheduleSyncManager.getInstance().sync(null);
    }

    @Override
    public void onResume() {
        super.onResume();
    }

    @Override
    public void onPause() {
        super.onPause();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mLastSyncTimeTimer.cancel();
        unregistObservers();
    }

    /**
     * View初始化
     */
    private void initView(){
        mScheduleNone = mContentView.findViewById(R.id.schedule_none);
        initScheduleList();
    }

    /**
     * 设置view的点击事件
     */
    private void setViewClick(){
        mContentView.findViewById(R.id.schedule_none_content).setOnClickListener(this);
    }

    private void initScheduleList(){
        mNonPullToRefresh = (PullToRefreshWebView) mContentView.findViewById(R.id.schedule_none_pull_to_refresh);
        mScheduleList = (ScheduleListView) mContentView.findViewById(R.id.my_schedule_list);

        mScheduleList.getLoadingLayoutProxy().setPullLabel(getString(R.string.pull_to_sync));
        mNonPullToRefresh.getLoadingLayoutProxy().setPullLabel(getString(R.string.pull_to_sync));

        mScheduleList.getLoadingLayoutProxy().setReleaseLabel(getString(R.string.release_to_sync));
        mNonPullToRefresh.getLoadingLayoutProxy().setReleaseLabel(getString(R.string.release_to_sync));

        mScheduleList.getLoadingLayoutProxy().setRefreshingLabel(getString(R.string.sync_ing));
        mNonPullToRefresh.getLoadingLayoutProxy().setRefreshingLabel(getString(R.string.sync_ing));

        initLastSyncTimeTimer();

        mScheduleList.setOnRefreshListener(this);
        mNonPullToRefresh.setOnRefreshListener(this);

        mScheduleList.getRefreshableView().setSelector(R.color.common_transparent); // 取消默认的item点击变色
        mScheduleList.setOnScrollListener(this);
        if(AccountManager.getInstance().getLoginType() == AccountManager.LOGIN_TYPE_NOUSER){
            // 非注册用户使用不需要下拉刷新同步功能
            mScheduleList.setMode(PullToRefreshBase.Mode.DISABLED);
            mNonPullToRefresh.setMode(PullToRefreshBase.Mode.DISABLED);
        } else{
            mScheduleList.setMode(PullToRefreshBase.Mode.PULL_FROM_START);
            mNonPullToRefresh.setMode(PullToRefreshBase.Mode.PULL_FROM_START);
        }

        mScheduleListAdapter = new ScheduleListAdapter(getActivity(), mScheduleList, ScheduleListAdapter.SORT_BY_FUTURE);
        mScheduleList.setAdapter(mScheduleListAdapter);
        mScheduleList.setOnItemClickListener(mScheduleListAdapter);
    }

    /**
     * 计划列表滑到顶部
     */
    public void scrollToTop(){
        mScheduleList.getRefreshableView().smoothScrollToPosition(0);
    }

    /**
     * 下拉刷新的最近一次更新时间刷新定时器初始化
     */
    private void initLastSyncTimeTimer(){
        mLastSyncTimeTimer = new Timer();
        TimerTask lastSyncTimeTimerTask = new TimerTask() {
            @Override
            public void run() {

                if(getActivity() == null){
                    mLastSyncTimeTimer.cancel();
                    return;
                }

                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        refreshLastUpdateLabel();
                    }
                });
            }
        };

        mLastSyncTimeTimer.schedule(lastSyncTimeTimerTask, 0, TimeUtil.MINUTE_MILLIS);
    }

    /**
     * 下拉刷新最后一次更新时间设置
     */
    private void refreshLastUpdateLabel(){
        long lastSyncTime = SyncTimePref.getInstance().getlastSyncTime(AccountManager.getInstance().getUsername());
        String lastUpdateMsg = TimeUtil.getLastSyncTimeStr(lastSyncTime);
        mNonPullToRefresh.getLoadingLayoutProxy().setLastUpdatedLabel(lastUpdateMsg);
        mScheduleList.getLoadingLayoutProxy().setLastUpdatedLabel(lastUpdateMsg);

    }

    @Override
    public void onRefresh(final PullToRefreshBase refreshView) {

        // 同步
        syncByRefresh();

    }

    /**
     * 下拉刷新控件设置刷新结束
     */
    private void setRefreshComplete(){
        mScheduleList.onRefreshComplete();
        mNonPullToRefresh.onRefreshComplete();
    }

    /**
     * 新增计划
     */
    public void createNewSchedule(){

        mScheduleList.closeAllItemOptions();

        Intent intent = new Intent(getActivity(), EditScheduleActivity.class);
        intent.setAction(EditScheduleActivity.ACTION_CREATE);
        startActivity(intent);
    }

    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
    }

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
        if(totalItemCount > PAGE_SIZE){
            if ((firstVisibleItem + visibleItemCount == totalItemCount) && (totalItemCount != 0)) {
                // 滑动到底部
                ScheduleLog.v(TAG, "scorll to bottom then load more...");
                loadMore();
            }
        }
    }

    /**
     * 数据库加载数据
     */
    private void loadMore(){
        loadMore(PAGE_SIZE);
    }

    /**
     * 数据库加载数据
     *
     * @param size 加载数量
     */
    private void loadMore(int size){
        if(mLoadingMore){
            return;
        }

        mLoadingMore = true;

        Schedule lastData = mScheduleListAdapter.getLastSchedule();

        if(lastData == null){
            // 将在数据库中的"重复"计划的时间更新到下一个最近发生的计划时间
            RepeatScheduleUtil.updateRepeatScheduleDb();
        }

        List<Schedule> schedules = ScheduleTbl.getInstance().select(
                AccountManager.getInstance().getmUsernameMD5L16(),
                lastData == null ? 0 : lastData.getLocalId(),
                size,
                lastData == null ? System.currentTimeMillis() : lastData.getBeginTime(),
                true,
                false
        );

        mScheduleListAdapter.addData(schedules);
        setScheduleListViewVisibility();

        mLoadingMore = false;
    }

    /**
     * 设置计划listview和无数据提示的显示
     */
    private void setScheduleListViewVisibility(){
        if(mScheduleListAdapter.getCount() > 0){
            mScheduleList.setVisibility(View.VISIBLE);
            mScheduleNone.setVisibility(View.GONE);
        } else{
            mScheduleList.setVisibility(View.GONE);
            mScheduleNone.setVisibility(View.VISIBLE);
        }
    }

    @Override
    public void onClick(View view) {
        if(view.getId() == R.id.schedule_none_content){
            createNewSchedule();

        }
    }

    /**
     * 注册观察者通知
     */
    private void registObservers(){
        ObserverManager.getInstance().registerUpdateScheduleToUi(this);
        ObserverManager.getInstance().registerSyncListener(this);
    }

    /**
     * 注销观察者通知
     */
    private void unregistObservers(){
        ObserverManager.getInstance().unregisterUpdateScheduleToUi(this);
        ObserverManager.getInstance().unregisterSyncListener(this);
    }

    @Override
    public void update(final Schedule schedule) {
        mHandler.post(new Runnable() {
            @Override
            public void run() {

                if (schedule.getBeginTime() > System.currentTimeMillis()
                        && !schedule.isDeleted()) {

                    boolean needUpdateToAdapter = true;

                    Schedule lastData = mScheduleListAdapter.getLastSchedule();


                    if (lastData != null
                            && (schedule.getBeginTime() > lastData.getBeginTime()
                            || (schedule.getBeginTime() == lastData.getBeginTime() && schedule.getLocalId() > lastData.getLocalId()))
                            && mScheduleListAdapter.getCount() >= PAGE_SIZE) {
                        // 这种情况 可能有数据库中的数据存在两者之间 因此选择不添加到界面 等用户滑到底部加载更多
                        needUpdateToAdapter = false;
                    }

                    if (needUpdateToAdapter) {
                        if (mScheduleListAdapter.existData(schedule.getLocalId())) {
                            // 更新到界面
                            mScheduleListAdapter.updateData(schedule);
                        } else {
                            // 界面上不存在该条记录，追加到界面
                            mScheduleListAdapter.addData(schedule);
                            setScheduleListViewVisibility();
                        }
                    } else {
                        mScheduleListAdapter.removeData(schedule.getLocalId());
                        setScheduleListViewVisibility();
                    }

                } else {
                    mScheduleListAdapter.removeData(schedule.getLocalId());
                    setScheduleListViewVisibility();
                }
            }
        });

    }

    /**
     * 下拉刷新同步数据
     */
    private void syncByRefresh(){
        ScheduleSyncManager.getInstance().sync(new ObserverIfaces.SyncListener() {
            @Override
            public void netWorkError() {
                mHandler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        setRefreshComplete();
                    }
                }, REFRESH_COMPLETE_DELAY);
                ScheduleToast.makeScheduleToastS(R.string.sync_failed_network_error).show();
            }

            @Override
            public void noSync() {
                mHandler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        setRefreshComplete();
                    }
                }, REFRESH_COMPLETE_DELAY);

            }

            @Override
            public void syncSuccess(List<Integer> submitedLocalIds, Map<Integer, Long> addedServerIds) {
                mHandler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        setRefreshComplete();
                    }
                }, REFRESH_COMPLETE_DELAY);

            }

            @Override
            public void newData(final List<Schedule> addList, final List<Schedule> updateList, final List<Schedule> deleteList) {
                // do nothing
            }

            @Override
            public void responseFailed(String returnCode) {
                // 同步失败
                mHandler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        setRefreshComplete();
                    }
                }, REFRESH_COMPLETE_DELAY);
                ScheduleToast.makeScheduleToastS(R.string.sync_failed).show();
            }
        });
    }

    @Override
    public void netWorkError() {
        // do noting
    }

    @Override
    public void noSync() {
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                refreshLastUpdateLabel();
            }
        });
    }

    @Override
    public void syncSuccess(List<Integer> submitedLocalIds, Map<Integer, Long> addedServerIds) {
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                refreshLastUpdateLabel();
            }
        });

        mScheduleListAdapter.setSubmitedAndServerIdWithoutNotify(submitedLocalIds, addedServerIds);
    }

    @Override
    public void newData(List<Schedule> addList, List<Schedule> updateList, List<Schedule> deleteList) {
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                int size = mScheduleListAdapter.getCount();
                if(size < PAGE_SIZE){
                    size = PAGE_SIZE;
                }
                mScheduleListAdapter.clearWithOutNotify();
                loadMore(size);
            }
        });
    }

    @Override
    public void responseFailed(String returnCode) {
        // do noting
    }
}
